package io.esir.permission;

import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import android.support.v4.content.ContextCompat;

import io.esir.permission.target.Target;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * DefaultRequest
 * Created by Huangrc on 2017/10/23.
 */

public class DefaultRequest implements
        Request,
        PermissionActivity.RationaleListener,
        PermissionActivity.PermissionListener {
    private static final String TAG = "AndPermission";

    private Target target;

    private int mRequestCode;
    private String[] mPermissions;
    private Object mCallback;
    private RationaleListener mRationaleListener;

    private String[] mDeniedPermissions;

    DefaultRequest(Target target) {
        if (target == null) {
            throw new IllegalArgumentException("The target can not be null.");
        }
        this.target = target;
    }


    @Override
    public void start() {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            callbackSucceed();
        } else {
            mDeniedPermissions = getDeniedPermissions(target.getContext(), mPermissions);
            // Denied mPermissions size > 0.
            if (mDeniedPermissions.length > 0) {
                // Remind users of the purpose of mPermissions.
                PermissionActivity.setRationaleListener(this);
                Intent intent = new Intent(target.getContext(), PermissionActivity.class);
                intent.putExtra(PermissionActivity.ARGS_PERMISSIONS, mDeniedPermissions);
                target.startActivity(intent);
            } else { // All permission granted.
                callbackSucceed();
            }
        }
    }

    private String[] getDeniedPermissions(Context context, String[] permissions) {
        List<String> deniedList = new ArrayList<>(1);
        for (String permission : permissions) {
            if (ContextCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
                deniedList.add(permission);
            }
        }
        return deniedList.toArray(new String[deniedList.size()]);
    }

    private void callbackSucceed() {
        if (mCallback != null) {
            if (mCallback instanceof PermissionListener) {
                ((PermissionListener) mCallback).onSucceed(mRequestCode, Arrays.asList(mPermissions));
            }/* else {
                callbackAnnotation(mCallback, mRequestCode, PermissionYes.class, Arrays.asList(mPermissions));
            }*/
        }
    }

    private void callbackFailed(List<String> deniedList) {
        if (mCallback != null) {
            if (mCallback instanceof PermissionListener) {
                ((PermissionListener) mCallback).onFailed(mRequestCode, deniedList);
            }/* else {
                callbackAnnotation(mCallback, mRequestCode, PermissionNo.class, deniedList);
            }*/
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    public void onRationaleResult(boolean showRationale) {
        if (showRationale && mRationaleListener != null) {
            mRationaleListener.showRequestPermissionRationale(mRequestCode, this);
        } else {
            resume();
        }
    }

    @NonNull
    @Override
    public Request permission(String... permissions) {
        this.mPermissions = permissions;
        return this;
    }

    @NonNull
    @Override
    public Request permission(String[]... permissionsArray) {
        List<String> permissionList = new ArrayList<>();
        for (String[] permissions : permissionsArray) {
            permissionList.addAll(Arrays.asList(permissions));
        }
        this.mPermissions = permissionList.toArray(new String[permissionList.size()]);
        return this;
    }

    @NonNull
    @Override
    public Request rationale(RationaleListener listener) {
        this.mRationaleListener = listener;
        return this;
    }

    @NonNull
    @Override
    public Request requestCode(int requestCode) {
        this.mRequestCode = requestCode;
        return this;
    }

    @NonNull
    @Override
    public Request callback(Object callback) {
        this.mCallback = callback;
        return this;
    }

    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    public void resume() {
        PermissionActivity.setPermissionListener(this);
        Intent intent = new Intent(target.getContext(), PermissionActivity.class);
        intent.putExtra(PermissionActivity.ARGS_PERMISSIONS, mDeniedPermissions);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        target.startActivity(intent);
    }

    @Override
    public void onRequestPermissionsResult(@NonNull String[] permissions, @NonNull int[] grantResults) {
        List<String> deniedList = new ArrayList<>();
        for (int i = 0; i < permissions.length; i++) {
            if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
                deniedList.add(permissions[i]);
            }
        }

        if (deniedList.isEmpty()) {
            callbackSucceed();
        } else {
            callbackFailed(deniedList);
        }
    }
}
